/*
 * =====================================================================================
 *
 *       Filename:  strSpliter.c
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  12/04/13 10:49:14
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Andy (gk), andy.y.li@163.com
 *        Company:  gl
 *
 * =====================================================================================
 */

#include <string.h>
#include "strSpliter.h"
#include <stdlib.h>
#include <errno.h>

void copyStr(const char *src,char *dst,int len)
{
    int idx;
    for(idx = 0; idx < len; idx++) {
        dst[idx] = src[idx];
    }
    dst[--idx] = '\0';
}

char ** splitStr(StrSpliter this,const char *str,const char *delimeter)
{
    if (this == NULL){
        return NULL;
    }
    this->result = (char **)malloc(sizeof(char *) * 1);
    memset(this->result,0,sizeof(char *) * 1);
    const char *p = str;
    const char *pos = str;
    this->len = 1;
    char **pp = NULL;
    while(*p != '\0'){
        char *temp;
        char *tt;
        int l;
        pos = strstr(p,delimeter);
        if (pos == NULL){
            if (this->len != 1){
                pp = (char **)realloc(this->result,sizeof(char *) * this->len);
                if (pp){
                    this->result = pp;
                }
                else{
                    fprintf(stderr,"realloc error: %s\n",strerror(errno));
                    this->free(this);
                    return NULL;
                }
            }
            l = strlen(p) + 1;
            temp = (char *)malloc(sizeof(char) * l);
            memset(temp,0,sizeof(char) * l);
            tt = temp;
            copyStr(p,temp,l);
            this->result[this->len - 1] = tt;
            return this->result;
        }

        l = pos - p + 1;
        if (l == 1){
            p +=  strlen(delimeter);
            continue;
        }

        temp = (char *)malloc(sizeof(char) * l);
        memset(temp,0,sizeof(char) * l);
        tt = temp;
        copyStr(p,temp,l);
        pp = (char **)realloc(this->result,sizeof(char *) * this->len);
        if (pp){
            this->result = pp;
        }
        else{
            fprintf(stderr,"realloc error: %s\n",strerror(errno));
            this->free(this);
            return NULL;
        }

        this->result[this->len - 1] = tt;
        this->len++;
        p +=  l + strlen(delimeter) - 1;
    }
    return this->result;
}

void freeStrs(StrSpliter this)
{
    if (this == NULL || this->result == NULL){
        return;
    }
    int idx;
    for(idx = 0;idx < this->len;++idx){
        if (this->result[idx]){
            free(this->result[idx]);
            this->result[idx] = NULL;
        }
    }
    free(this->result);
    this->result = NULL;
    this->len = 0;
    free(this);
}

void showList(StrSpliter this)
{
    printf("showList...\n");
    if (this == NULL || this->result == NULL){
        return;
    }
    int idx;
    for(idx = 0;idx < this->len;++idx){
        printf("%d: %s\n",idx,this->result[idx]);
    }
}

char * getField(StrSpliter this, int n)
{
    if (this == NULL || n + 1 > this->len){
        return "";
    }
    return this->result[n];
}


int len(StrSpliter this)
{
    if (this == NULL){
        return 0;
    }
    return this->len;
}

StrSpliter getStrSpliter()
{
    StrSpliter spliter = (StrSpliter)malloc(sizeof(StrSplit));
    spliter->result = NULL;
    spliter->len = 0;
    spliter->split = splitStr;
    spliter->length = len;
    spliter->show = showList;
    spliter->field = getField;
    spliter->free = freeStrs;

    return spliter;
}

